#include "EventLoopThread.h"
#include "EventLoop.h"

EventLoopThread::EventLoopThread(const ThreadInitCallback &cb, const std::string &name)
    : loop_(nullptr), exiting_(false), thread_(std::bind(&EventLoopThread::threadFunc, this), name), mutex_(), cond_(), callback_(cb)
{
}

EventLoopThread::~EventLoopThread()
{
    exiting_ = true;
    if (loop_ != nullptr)
    {
        loop_->quit();  // EventLoop退出事件循环
        thread_.join(); // 主线程主动等待新线程结束，回收线程资源
    }
}

EventLoop *EventLoopThread::startLoop()
{
    thread_.start(); // 启动（创建）底层的新线程，触发threadFunc（）执行

    EventLoop *loop = nullptr;
    {
        std::unique_lock<std::mutex> lock(mutex_);
        // 当loop_为空时，必须主动等待新线程中loop_被初始化
        while (loop_ == nullptr)
        {
            cond_.wait(lock); // 主动等待，释放锁并阻塞，直到被唤醒
        }
        loop = loop_; // 获取初始化完成的EventLoop指针
    }
    return loop;
}

// 创建的新线程执行的线程函数
void EventLoopThread::threadFunc()
{
    // 在新线程栈上创建EventLoop对象（与该线程绑定），one loop per thread
    EventLoop loop;
    if (callback_)
    {
        callback_(&loop); // 执行用户初始化回调（设置线程名称）
    }

    {
        std::unique_lock<std::mutex> lock(mutex_);
        loop_ = &loop;      // 将loop_指向新创建的EventLoop
        cond_.notify_one(); // 通知主线程，loop_已初始化完成
    }
    loop.loop(); // 启动事件循环，执行EventLoop的loop（）=> 开启Poller.poll()（阻塞，直到loop_.quit（）被调用）

    // 事件循环退出后清理
    std::unique_lock<std::mutex> lock(mutex_);
    loop_ = nullptr;
}